package dycaps

import (
	"fmt"
	"sync"
	"time"
)

// RBCAdapter 将实际的RBC实现适配到CBR接口
type RBCAdapter struct {
	nodeID      int
	n           int
	f           int
	instanceID  int
	msgInCh     chan Message
	msgOutCh    chan Message
	deliverCh   chan []byte
	mu          sync.Mutex
	delivered   map[int][]byte
	initialized bool
}

// NewRBCAdapter 创建新的RBC适配器
func NewRBCAdapter(nodeID, n, f, instanceID int) *RBCAdapter {
	return &RBCAdapter{
		nodeID:     nodeID,
		n:          n,
		f:          f,
		instanceID: instanceID,
		msgInCh:    make(chan Message, 100),
		msgOutCh:   make(chan Message, 100),
		deliverCh:  make(chan []byte, 10),
		delivered:  make(map[int][]byte),
	}
}

// Initialize 初始化RBC适配器
func (r *RBCAdapter) Initialize() error {
	r.mu.Lock()
	defer r.mu.Unlock()

	if r.initialized {
		return nil
	}

	// 启动消息处理器
	go r.messageHandler()
	
	r.initialized = true
	return nil
}

// Broadcast 广播数据
func (r *RBCAdapter) Broadcast(data []byte) error {
	if !r.initialized {
		if err := r.Initialize(); err != nil {
			return fmt.Errorf("failed to initialize: %w", err)
		}
	}

	// 创建RBC发送消息
	msg := Message{
		Tag:      ADKR_RBC,
		Source:   r.nodeID,
		Dest:     -1, // 广播
		Round:    r.instanceID,
		Instance: r.instanceID,
		Payload:  data,
	}

	// 发送到输出通道
	select {
	case r.msgOutCh <- msg:
		return nil
	case <-time.After(5 * time.Second):
		return fmt.Errorf("broadcast timeout")
	}
}

// Receive 接收已投递的数据
func (r *RBCAdapter) Receive() ([]byte, error) {
	select {
	case data := <-r.deliverCh:
		return data, nil
	case <-time.After(30 * time.Second):
		return nil, fmt.Errorf("receive timeout")
	}
}

// ReceiveWithTimeout 带超时的接收
func (r *RBCAdapter) ReceiveWithTimeout(timeout time.Duration) ([]byte, error) {
	select {
	case data := <-r.deliverCh:
		return data, nil
	case <-time.After(timeout):
		return nil, fmt.Errorf("receive timeout")
	}
}

// HandleMessage 处理接收到的消息
func (r *RBCAdapter) HandleMessage(msg Message) {
	select {
	case r.msgInCh <- msg:
	default:
		// 通道满，丢弃消息
	}
}

// messageHandler 处理RBC消息
func (r *RBCAdapter) messageHandler() {
	echoCount := make(map[string]int)
	readyCount := make(map[string]int)
	sentEcho := make(map[string]bool)
	sentReady := make(map[string]bool)

	for msg := range r.msgInCh {
		if msg.Instance != r.instanceID {
			continue
		}

		dataHash := hashData(msg.Payload)

		switch msg.Tag {
		case ADKR_RBC:
			// SEND消息 - 发送ECHO
			if !sentEcho[dataHash] {
				echoMsg := Message{
					Tag:      ADKR_RBC_ECHO,
					Source:   r.nodeID,
					Dest:     -1,
					Round:    r.instanceID,
					Instance: r.instanceID,
					Payload:  msg.Payload,
				}
				r.msgOutCh <- echoMsg
				sentEcho[dataHash] = true
			}

		case ADKR_RBC_ECHO:
			// ECHO消息 - 计数
			echoCount[dataHash]++
			
			// 收到 (n+f+1)/2 个ECHO后发送READY
			if echoCount[dataHash] >= (r.n+r.f+1)/2 && !sentReady[dataHash] {
				readyMsg := Message{
					Tag:      ADKR_RBC_READY,
					Source:   r.nodeID,
					Dest:     -1,
					Round:    r.instanceID,
					Instance: r.instanceID,
					Payload:  msg.Payload,
				}
				r.msgOutCh <- readyMsg
				sentReady[dataHash] = true
			}

		case ADKR_RBC_READY:
			// READY消息 - 计数
			readyCount[dataHash]++
			
			// 收到 f+1 个READY后发送READY（如果还没发送）
			if readyCount[dataHash] >= r.f+1 && !sentReady[dataHash] {
				readyMsg := Message{
					Tag:      ADKR_RBC_READY,
					Source:   r.nodeID,
					Dest:     -1,
					Round:    r.instanceID,
					Instance: r.instanceID,
					Payload:  msg.Payload,
				}
				r.msgOutCh <- readyMsg
				sentReady[dataHash] = true
			}
			
			// 收到 2f+1 个READY后投递
			if readyCount[dataHash] >= 2*r.f+1 {
				r.mu.Lock()
				if _, exists := r.delivered[r.instanceID]; !exists {
					r.delivered[r.instanceID] = msg.Payload
					r.mu.Unlock()
					
					select {
					case r.deliverCh <- msg.Payload:
					default:
					}
				} else {
					r.mu.Unlock()
				}
			}
		}
	}
}

// GetOutputChannel 获取输出消息通道
func (r *RBCAdapter) GetOutputChannel() <-chan Message {
	return r.msgOutCh
}

// Close 关闭适配器
func (r *RBCAdapter) Close() {
	close(r.msgInCh)
}

// MVBAAdapter 将实际的MVBA实现适配到CBR接口
type MVBAAdapter struct {
	nodeID      int
	n           int
	f           int
	instanceID  int
	inputCh     chan []byte
	decideCh    chan []byte
	msgInCh     chan Message
	msgOutCh    chan Message
	mu          sync.Mutex
	decided     bool
	decisionVal []byte
	initialized bool
}

// NewMVBAAdapter 创建新的MVBA适配器
func NewMVBAAdapter(nodeID, n, f, instanceID int) *MVBAAdapter {
	return &MVBAAdapter{
		nodeID:     nodeID,
		n:          n,
		f:          f,
		instanceID: instanceID,
		inputCh:    make(chan []byte, 1),
		decideCh:   make(chan []byte, 1),
		msgInCh:    make(chan Message, 100),
		msgOutCh:   make(chan Message, 100),
	}
}

// Initialize 初始化MVBA适配器
func (m *MVBAAdapter) Initialize() error {
	m.mu.Lock()
	defer m.mu.Unlock()

	if m.initialized {
		return nil
	}

	// 启动MVBA协议
	go m.runMVBA()
	
	m.initialized = true
	return nil
}

// Propose 提出提案
func (m *MVBAAdapter) Propose(proposal []byte) error {
	if !m.initialized {
		if err := m.Initialize(); err != nil {
			return fmt.Errorf("failed to initialize: %w", err)
		}
	}

	select {
	case m.inputCh <- proposal:
		return nil
	case <-time.After(5 * time.Second):
		return fmt.Errorf("propose timeout")
	}
}

// Decide 等待决定
func (m *MVBAAdapter) Decide() ([]byte, error) {
	select {
	case decision := <-m.decideCh:
		return decision, nil
	case <-time.After(60 * time.Second):
		return nil, fmt.Errorf("decide timeout")
	}
}

// HandleMessage 处理接收到的消息
func (m *MVBAAdapter) HandleMessage(msg Message) {
	m.mu.Lock()
	defer m.mu.Unlock()
	
	// 检查通道是否已关闭
	if m.msgInCh == nil {
		return
	}
	
	select {
	case m.msgInCh <- msg:
	default:
		// 通道满，丢弃消息
	}
}

// runMVBA 运行MVBA协议
func (m *MVBAAdapter) runMVBA() {
	// 这是一个简化的MVBA实现
	// 在实际部署中，应该调用完整的MVBA实现
	
	// 收集提案
	proposals := make(map[string]int)
	var myProposal []byte
	
	// 等待自己的提案
	select {
	case myProposal = <-m.inputCh:
	case <-time.After(30 * time.Second):
		return
	}
	
	// 广播提案
	proposeMsg := Message{
		Tag:      ADKR_MVBA,
		Source:   m.nodeID,
		Dest:     -1,
		Round:    m.instanceID,
		Instance: m.instanceID,
		Payload:  myProposal,
	}
	m.msgOutCh <- proposeMsg
	
	// 计数自己的提案
	proposalHash := hashData(myProposal)
	proposals[proposalHash] = 1
	
	// 收集其他节点的提案
	timeout := time.After(10 * time.Second)
	for {
		select {
		case msg := <-m.msgInCh:
			if msg.Tag == ADKR_MVBA && msg.Instance == m.instanceID {
				hash := hashData(msg.Payload)
				proposals[hash]++
				
				// 如果收到 f+1 个相同的提案，决定该值
				if proposals[hash] >= m.f+1 {
					m.mu.Lock()
					if !m.decided {
						m.decided = true
						m.decisionVal = msg.Payload
						m.decideCh <- msg.Payload
					}
					m.mu.Unlock()
					return
				}
			}
		case <-timeout:
			// 超时，选择收到最多的提案
			m.mu.Lock()
			if !m.decided {
				maxCount := 0
				var decision []byte
				for hash, count := range proposals {
					if count > maxCount {
						maxCount = count
						decision = []byte(hash) // 简化处理
					}
				}
				m.decided = true
				m.decisionVal = decision
				m.decideCh <- decision
			}
			m.mu.Unlock()
			return
		}
	}
}

// GetOutputChannel 获取输出消息通道
func (m *MVBAAdapter) GetOutputChannel() <-chan Message {
	return m.msgOutCh
}

// Close 关闭适配器
func (m *MVBAAdapter) Close() {
	m.mu.Lock()
	defer m.mu.Unlock()
	
	if m.inputCh != nil {
		close(m.inputCh)
		m.inputCh = nil
	}
	
	if m.msgInCh != nil {
		close(m.msgInCh)
		m.msgInCh = nil
	}
}

// ThresholdSigAdapter BLS阈值签名适配器
type ThresholdSigAdapter struct {
	nodeID    int
	n         int
	f         int
	secretKey []byte
	publicKey []byte
	mu        sync.RWMutex
}

// NewThresholdSigAdapter 创建新的阈值签名适配器
func NewThresholdSigAdapter(nodeID, n, f int, secretKey, publicKey []byte) *ThresholdSigAdapter {
	return &ThresholdSigAdapter{
		nodeID:    nodeID,
		n:         n,
		f:         f,
		secretKey: secretKey,
		publicKey: publicKey,
	}
}

// Sign 对数据进行签名
func (t *ThresholdSigAdapter) Sign(data []byte) ([]byte, error) {
	// 这里应该使用实际的BLS签名
	// 目前使用简化实现
	signature := make([]byte, 64)
	hash := hashData(data)
	copy(signature, hash)
	copy(signature[32:], t.secretKey[:32])
	return signature, nil
}

// Verify 验证签名
func (t *ThresholdSigAdapter) Verify(data []byte, signature []byte) bool {
	// 这里应该使用实际的BLS验证
	// 目前使用简化实现
	if len(signature) < 64 {
		return false
	}
	return true
}

// Combine 组合签名份额
func (t *ThresholdSigAdapter) Combine(signatures [][]byte) ([]byte, error) {
	if len(signatures) < t.f+1 {
		return nil, fmt.Errorf("insufficient signatures: got %d, need %d", len(signatures), t.f+1)
	}

	// 这里应该使用实际的BLS签名聚合
	// 目前返回第一个签名作为组合结果
	combined := make([]byte, 64)
	if len(signatures) > 0 && len(signatures[0]) >= 64 {
		copy(combined, signatures[0])
	}
	
	return combined, nil
}

// PartialVerify 部分验证签名份额
func (t *ThresholdSigAdapter) PartialVerify(data []byte, signature []byte, signerID int) bool {
	// 简化实现
	return len(signature) >= 64
}

// hashData 计算数据哈希
func hashData(data []byte) string {
	// 简单哈希函数
	h := 0
	for _, b := range data {
		h = h*31 + int(b)
	}
	return fmt.Sprintf("%x", h)
}

